//
//  CZHomeViewController.swift
//  微博08
//
//  Created by apple on 16/2/26.
//  Copyright © 2016年 itcast. All rights reserved.
//

import UIKit
import SVPullToRefresh


/*
    将带表情名称文本的转成带表情图片的文本
        1.找出表情名称
        2.找到表情模型,表情模型里面既有文本又有图片.
        3.将模型转成带图片的附件,在转成属性文本
        4.在本文中将表情名称替换成表情图片
*/

class CZHomeViewController: CZBaseTableViewController {
    
    // MARK: - 属性
    private let PullDownHeight: CGFloat = 44
    
    private let reuseIdentifier = "cellId"
    
    // 存储性属性
    var statuses: [CZStatus]? {
        didSet {
            // 16.当别人给statuses属性赋值后,再刷新tableView
            tableView.reloadData()
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 只有用户登录了才需要做下面的操作
        if !CZUserAccountViewModel.sharedInstance.userLogin {
            return
        }

        setupNavigationBar()
        prepareTableView()
        
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "linkTextClick:", name: LinkTextClickNotification, object: nil)
        
        UIApplication.sharedApplication().keyWindow?.showInCenter()
        
        // 1.控制器的加载微博数据方法
//        loadStatus()
    }
    
    deinit {
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }
    
    func linkTextClick(notification: NSNotification) {
        let addr = notification.userInfo?[LinkTextClickLinkKey] as! String
        
        // 弹出控制器
        let homeWebViewVC = CZHomeWebViewController()
        homeWebViewVC.addr = addr
        
        presentViewController(UINavigationController(rootViewController: homeWebViewVC), animated: true, completion: nil)
    }
    
    private func prepareTableView() {
        // 注册cell
        tableView.registerClass(CZStatusCell.self, forCellReuseIdentifier: reuseIdentifier)
        
        // 取消分割线
        tableView.separatorStyle = UITableViewCellSeparatorStyle.None
        
        /*
        tableView cell的高度根据内容自适应
        1.设置预估行高
        2.设置rowHeight = UITableViewAutomaticDimension
        3.设置好约束.contentView
        */
//        tableView.estimatedRowHeight = 150
        tableView.rowHeight = UITableViewAutomaticDimension
        
        // 设置刷新控件
        refreshControl = CZRefreshControl()
        refreshControl?.addTarget(self, action: "loadNewStatus", forControlEvents: UIControlEvents.ValueChanged)
        
        // 开始刷新, 只会让刷新控件进入刷新状态,并不会触发UIControlEvents.ValueChanged事件
        refreshControl?.beginRefreshing()
        
//        UIRefreshControl.printIvars()
        refreshControl?.setValue(60, forKey: "_snappingHeight")
        
        // 我们主动触发refreshControl的UIControlEvents.ValueChanged
        refreshControl?.sendActionsForControlEvents(UIControlEvents.ValueChanged)
    }
    
    /**
     加载最新微博数据,调用场景:1.一进入程序 2.用户用手拖动下拉刷新
     */
    func loadNewStatus() {
        // 2.调用 statusVM的loadStatus加载数据,准备闭包
        
        // 当statuses有值的时候,获取到微博id最大的这条,整个微博数组的第一条就是id最大的微博
        let since_id = statuses?.first?.id ?? 0
        
        statusVM.loadStatus(since_id, max_id: 0) { (statuses, error) -> () in
            // 让刷新控件回到没有加载的状态
            self.refreshControl?.endRefreshing()
            
            // 15.判断错误
            if error != nil {
                print("加载最新微博数据 博数据出错了: \(error)")
                return
            }
            
            let count = statuses?.count ?? 0
            print("加载到的微博数据: \(count)")
            
            if since_id > 0 {
                self.showPullDownTipView(count)
            }
            
            if count == 0 {
                return
            }
            
            // 15.之前没有微博数据
            if since_id == 0 {
                self.statuses = statuses
                
                // 只有第一次加载完数据后才需要上拉加载更多
                self.tableView.addInfiniteScrollingWithActionHandler { () -> Void in
                    self.loadMoreStatus()
                }
            } else {
                // 之前有微博数据,将加载到的新微博数据拼接到现有数据的前面
                self.statuses = statuses! + self.statuses!
            }
            
            print("下拉刷新最终的微博数据: \(self.statuses?.count)")
        }
    }
    
    /**
     只有下拉刷新才显示
     
     - parameter count: 微博的数量
     */
    private func showPullDownTipView(count: Int) {
        pullDownTipLabel.text = count == 0 ? "没有获得新的微博数据" : "更新了\(count)条微博"
        // 动画下来
        let duration = 1.0
        UIView.animateWithDuration(duration, animations: { () -> Void in
            self.pullDownTipLabel.frame.origin.y = self.PullDownHeight
            }) { (_) -> Void in
                // 停一段时间在动画回去
                UIView.animateWithDuration(duration, delay: 0.5, options: UIViewAnimationOptions(rawValue: 0), animations: { () -> Void in
                    self.pullDownTipLabel.frame.origin.y = -self.PullDownHeight - 20
                    }, completion: nil)
        }
    }
    
    /**
     上拉加载更多数据
     */
    func loadMoreStatus() {
        // 获取所有微博数据中id最小的微博
        let max_id = statuses?.last?.id ?? 0
        statusVM.loadStatus(0, max_id: max_id) { (statuses, error) -> () in
            // 让第SVPullToRefresh隐藏.
            self.tableView.infiniteScrollingView.stopAnimating()
            
            if error != nil {
                print("上拉加载更多数据 加载微博数据出错了: \(error)")
                return
            }
            
            // 加载更多微博数据成功了
            let count = statuses?.count ?? 0
            
            if count == 0 {
                print("上拉加载没有获取到微博数据")
                return
            }
            
            // 将获取到的数据拼接在现有数据的后面
            self.statuses = self.statuses! + statuses!
        }
    }
    
    /**
     设置导航栏
     */
    private func setupNavigationBar() {
        setupBarButtonItem()
        setupTitleView()
    }
    
    /**
     设置导航栏左右item
     */
    private func setupBarButtonItem() {
        // 方式4
        navigationItem.leftBarButtonItem = UIBarButtonItem(imageName: "navigationbar_friendsearch")
        navigationItem.rightBarButtonItem = UIBarButtonItem(imageName: "navigationbar_pop")
    }
    
    private func setupTitleView() {
        let name = CZUserAccountViewModel.sharedInstance.userAccount?.screen_name ?? "没有用户名称"
        // 创建按钮
        let titleButton = CZTitleView(title: name)
        
        // 添加点击事件
        titleButton.addTarget(self, action: "titleButtonClick:", forControlEvents: UIControlEvents.TouchUpInside)
        
        navigationItem.titleView = titleButton
    }
    
    // MARK: - 按钮点击事件
    func titleButtonClick(button: UIButton) {
        // 根据按钮的selected来确定按钮旋转的角度
        // selected = false, 箭头向下
        // selected = true, 箭头向上
        
        button.selected = !button.selected
        
        UIView.animateWithDuration(0.25) { () -> Void in
            button.imageView?.transform = button.selected ? CGAffineTransformMakeRotation(CGFloat(M_PI - 0.001)) : CGAffineTransformIdentity
        }
        
        // 按钮选中的时候弹出Popover
        if button.selected {
            // UIpopoverViewController: 只能用在iPad上面
            // iOS8.0以后,使用 UIPopoverPresentationController 可以达到popover的效果
            
            // 1.加载sb
            let sb = UIStoryboard(name: "Popover", bundle: nil)
            
            // 2.创建控制器
            let popoverVC = sb.instantiateViewControllerWithIdentifier("popover")
            
            // 在iPhone上面设置Popover默认会适配成Modal
            popoverVC.modalPresentationStyle = UIModalPresentationStyle.Popover

            // 设置popoverPresentationController代理
            popoverVC.popoverPresentationController?.delegate = self
            popoverVC.popoverPresentationController?.sourceView = navigationItem.titleView
            popoverVC.popoverPresentationController?.sourceRect = navigationItem.titleView!.bounds
            
            // 设置弹出控制器显示的大小
            popoverVC.preferredContentSize = CGSize(width: 200, height: 5 * 44)
            
            presentViewController(popoverVC, animated: true, completion: nil)
        }
    }
    
    
    // MARK: - 懒加载
    /// 微博模型的ViewModel
    private lazy var statusVM: CZStatusViewModel = CZStatusViewModel()
    
    /// 下拉刷新的提示view
    private lazy var pullDownTipLabel: UILabel = {
        let label = UILabel(textColor: UIColor.whiteColor(), font: 16)
        label.frame = CGRect(origin: CGPoint(x: 0, y: -self.PullDownHeight - 20), size: CGSize(width: UIScreen.width, height: self.PullDownHeight))

        label.textAlignment = NSTextAlignment.Center
        
        label.backgroundColor = UIColor.orangeColor()
        
        self.navigationController?.navigationBar.insertSubview(label, atIndex: 0)
        
        return label
    }()
}

// MARK: - tableView相关
/*
    tableView优化:
        *.cell复用
        *.dequeue也要注意使用: 带 forIndexPath会调用多次,建议使用不带forIndexPath **
        *.设置预估行高不会一次性计算出所有cell的高度,只会计算出需要显示的cell的高度,等到cell即将显示的时候在来计算,不使用预估行高,在tableViewreloadData时就会算出所有cell的高度,如果需要界面流畅滑动建议不要预估行高
        *.不要在cellForRowAtIndexPath方法里面频繁创建和删除控件.应该使用懒加载,看得见得时候显示,看不见就隐藏
        *.cellForRowAtIndexPath不要在主线程做耗时的操作,耗时的操作在子线程进行.图片下载.文件的读取和写入 ***
        *.图片圆角最好不要使用layer.cornerRadius,采用裁剪图片
        *.cell里面的view的背景颜色最好是不透明的
        *.cell里面的控件frame.值最好都是整数
        *.有些不需要交互的控件直接使用layer显示出来
        *.行高尽量只算一次,然后缓存起来 **
        *.尽量不要在cellForRowAtIndexPath做太多的计算
        *.直接绘图
        *.cell里面的View的transform
        *.tableView滚动的时候,不要去做动画
        *.AsyncDisplayKit
*/
extension CZHomeViewController {
    
    override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        let status = statuses?[indexPath.row]
        
        // 1.判断模型有没有算过行高
        if let height = status?.height {
//            print("使用缓存行高: \(height)")
            return height
        }
        
        // 之前没有高度, 获取一个cell,只用来计算行高,不参与显示
        let cell = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier) as! CZStatusCell
        cell.status = status
        
        // 获取算出的尺寸
        let size = cell.systemLayoutSizeFittingSize(UILayoutFittingExpandedSize)
        
        // 保存行高
        status?.height = size.height

//        print("计算 heightForRowAtIndexPath indexPath: \(indexPath)")
        
        return size.height
    }
    
    // 显示多少个cell
    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // ??: ?? 前面的可选有值,就拆包,如果没有值,使用 ?? 后面的值
        return statuses?.count ?? 0
    }
    
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier) as! CZStatusCell
        
//        let cell = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier, forIndexPath: indexPath) as! CZStatusCell
        // 将微博的内容显示出来
        // statuses?也能赋值,看接收方的类型
        cell.status = statuses?[indexPath.row]
        
        return cell
    }
    
    // 是否需要高亮
    override func tableView(tableView: UITableView, shouldHighlightRowAtIndexPath indexPath: NSIndexPath) -> Bool {
        return false
    }
    
//    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
//        // 取消选中
//        tableView.deselectRowAtIndexPath(indexPath, animated: false)
//    }
}

extension CZHomeViewController: UIPopoverPresentationControllerDelegate {
    // 让iPhone上面可以显示popover效果
    func adaptivePresentationStyleForPresentationController(controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
        return UIModalPresentationStyle.None
    }
    
    // popover关闭时调用
    func popoverPresentationControllerDidDismissPopover(popoverPresentationController: UIPopoverPresentationController) {
        // 将标题按钮的箭头转下去
        let button = navigationItem.titleView as! CZTitleView
        titleButtonClick(button)
    }
    
//    func popoverPresentationControllerShouldDismissPopover(popoverPresentationController: UIPopoverPresentationController) -> Bool {
//        
//        // 将标题按钮的箭头转下去
//        let button = navigationItem.titleView as! CZTitleView
//        titleButtonClick(button)
//        return true
//    }
}
